﻿using System.Collections.Generic;
using System.Linq;
using FoosballEye.Model;

namespace FoosballEye.Repository
{
    using System;

    using FoosballEye.Model.Adapters;

    public class PlayerRepository : RepositoryBase<FoosballEyeDbContext>, IPlayerRepository
    {
        private const string Hawkeyeww = "HAWKEYEWW\\";

        public Player GetPlayer(int id)
        {
            return DataContext.Players.FirstOrDefault(x => x.Id == id && !x.Deleted);
        }

        public Player GetPlayer(string login)
        {
            return DataContext.Players.FirstOrDefault(x => x.Login.EndsWith(login.Replace("HAWKEYEWW",string.Empty)));
        }
        
        public PlayerFull GetPlayerFull(string login)
        {
            var aa = DataContext.Players.Where(x => x.Login.EndsWith(login.Replace("HAWKEYEWW", string.Empty)))
                .Select(a => new {
                    a.Id,
                    a.Login, 
                    a.AccountPoints, 
                    LodzOfficeRoom = a.LodzOfficeRoom.RoomName,
                    LastMatch = a.PlayerHistory.OrderByDescending(p => p.HIstoryInsertDate).AsEnumerable().FirstOrDefault(), 
                    NumberOfMatches = this.DataContext.GameTeams.Count(t => t.AttackerId == a.Id && !t.Deleted) + this.DataContext.GameTeams.Count(t => t.DefenderId == a.Id && !t.Deleted),
                    //NumberOfMatches = a.PlayerHistory.Count(x => x.PlayerId == a.Id && !x.Deleted),
                    Ranking = this.DataContext.Players.Count(p => p.AccountPoints > a.AccountPoints) + 1
                })
                .FirstOrDefault();

            var pointsHistoryTop100 =
                this.DataContext.PlayerHistories.Where(x => x.PlayerId == aa.Id && !x.Deleted)
                    .OrderByDescending(x => x.Id)
                    .Take(100)
                    .OrderBy(x => x.Id)
                    .Select(p => new { p.HIstoryInsertDate, p.AccountPoints })
                    .ToArray();

            var pointsHistory = pointsHistoryTop100
                    .Select(p => new PointData { TimeStamp = GetJavascriptTimestamp(p.HIstoryInsertDate), Points = p.AccountPoints })
                    .ToArray();

            return new PlayerFull{AccountPoints = aa.AccountPoints, 
                                  Login = aa.Login.Replace("HAWKEYEWW\\",string.Empty),
                                  LastMatch = aa.LastMatch != null ? aa.LastMatch.HIstoryInsertDate.ToString("M/d/yyyy HH:mm") : string.Empty, 
                                  LodzOfficeRoom = aa.LodzOfficeRoom, 
                                  NumberOfMatches = aa.NumberOfMatches,
                                  Ranking = aa.Ranking,
                                  PointsHistory = pointsHistory};
        }


        public static long GetJavascriptTimestamp(System.DateTime input)
        {
            System.TimeSpan span = new System.TimeSpan(System.DateTime.Parse("1/1/1970").Ticks);
            System.DateTime time = input.Subtract(span);
            return (long)(time.Ticks / 10000);
        }


        public List<Player> GetAllPlayers()
        {
            List<Player> players = 
                DataContext.Players.Where(x => !x.Deleted).OrderBy(x => x.Login).ToList();

            players.ForEach(x => x.Login = x.Login.Replace(Hawkeyeww, string.Empty));

            return players;
        }

        public List<PlayerBest> GetBestPlayers(int seasonId)
        {
            return
                DataContext.Players.OrderByDescending(x => x.AccountPoints)
                    //.Take(10)
                    .ToList()
                    .Select(
                        (x, i) => new PlayerBest { 
                            Login = x.Login.Replace(Hawkeyeww, string.Empty), 
                            Points = x.AccountPoints, 
                            Ranking = i + 1,
                            NumberOfGames = this.DataContext.GameTeams.Count(y => 
                                ((y.AttackerId == x.Id && !y.Deleted) || (y.DefenderId == x.Id && !y.Deleted)) && y.SeasonId == seasonId)
                        })
                    .ToList();

        }

        public List<PlayerBest> GetStatistics(int seasonId)
        {
            return
                DataContext.SeasonPlayerRankings
                    .Include("Player")
                    .Where(x => !x.Deleted && x.SeasonId == seasonId).OrderByDescending(x => x.AccountPoints)
                    .Take(10)
                    .ToList()
                    .Select(
                        (x, i) => new PlayerBest
                        {
                            Login = x.Player.Login.Replace(Hawkeyeww, string.Empty),
                            Points = x.AccountPoints,
                            Ranking = i + 1,
                            NumberOfGames = x.NumberOfMatches
                        })
                    .ToList();
        }
        
    }
}
